to do before publish

#remettre ligne de code general identification (trop long a calcul pour les test de knit) + remettre pour cluster 13 deux premiere ligne list..

#cluster 3 DP small, 8,10,16
#11 refaire text marqueur
#refaire cluster 13 avec annot one note pour petit iddentif des pop
#DP blast put cell cycle umap ? dans le fichier myc_pten_paper --> report mycpten..cccaintegration_modif

#revoir titre partie en fonction du papier
#refaire docker en verifiant que tout les librairies necessaire sont dowloand dedans

#verif tout comm sont bein en anglais

#CD8 vs CD4 remettre les calcul de fin marker pour le final et pas le load fichier qui est la poru gagner du temps

#change output path
#loading final object obtain with Experiment_preprocessing
SAMPLE1 <- "181031"
SAMPLE2 <- "190211"

if(! file.exists(paste0(OUTPUT_PATH, "T-Seurat-merged_clean-subset",".Robj"))){
print("You should start with Experiment_preprocessing.Rmd or dowload our final object 'T-Seurat-merged_clean-subset.Robj' ")
do <- FALSE
}else{ 
print ("You are starting analysis of our final Seurat object")
load(paste0(OUTPUT_PATH, "T-Seurat-merged_clean-subset",".Robj"))
do <- TRUE
}

[1] “You are starting analysis of our final Seurat object”

Creating tissue subset

Thymus subset

Idents(T.Seurat) <- "HTO"
T.Seurat.thymus <- subset(T.Seurat, idents = c("Myc- PTEN- thymus","MYC- thymus","PTEN- thymus","WT thymus"))
a <- t(margin.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$integrated_snn_res.1.8),2))
T.Seurat.spleen <- subset(T.Seurat, idents = c("Myc- PTEN- spleen","MYC- spleen","PTEN- spleen","WT spleen"))
b <- t(margin.table(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$integrated_snn_res.1.8),2))
c <- t((a/(a+b)*100))
c
##     
##      [,1]      
##   0    8.204812
##   1   16.918967
##   2   99.730942
##   3   99.634369
##   4    2.474794
##   5    1.868132
##   6   77.661431
##   7   95.885510
##   8   99.564270
##   9    3.139013
##   10  38.990826
##   11   3.240741
##   12   1.960784
##   13  15.763547
##   14  82.543641
##   15   9.595960
##   16  44.074074
##   17  37.327189
##   18  98.913043
##   19   0.000000
##   20  94.771242
##   21  99.264706
##   22  80.882353
##   23 100.000000
#Thymic populations
thymus.clusters <- rownames(as.data.frame(c[which(c[,1]>25),]))
Idents(T.Seurat.thymus) <- "integrated_snn_res.1.8"
T.Seurat.thymus <- subset(T.Seurat.thymus, idents = thymus.clusters)
DimPlot(T.Seurat.thymus)

Spleen subset

#Spleen populations
as.data.frame(100-c[which(c[,1]<75),])
##    100 - c[which(c[, 1] < 75), ]
## 0                       91.79519
## 1                       83.08103
## 4                       97.52521
## 5                       98.13187
## 9                       96.86099
## 10                      61.00917
## 11                      96.75926
## 12                      98.03922
## 13                      84.23645
## 15                      90.40404
## 16                      55.92593
## 17                      62.67281
## 19                     100.00000
spleen.clusters <- rownames(as.data.frame(c[which(c[,1]<75),]))
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
T.Seurat.spleen <- subset(T.Seurat.spleen, idents = spleen.clusters)
DimPlot(T.Seurat.spleen)

Manual clustering

Based on several markers we are adjusting our clusterging, similar cluster are then annotate as one.

Thymic clusters :

#Look at differentiation markers on thymic clusters
DotPlot(T.Seurat.thymus, features = c("percent.mito","Bmf","Trp53inp1","Tox2","Cd5","Cd69","Cd27","Rag1","Rag2","Cd4","Cd8a","Cd8b1","Uchl3","Mki67","Cdk1","Ptcra","Il2ra","Cd34")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme_dark(base_size = 14) + coord_flip()

#Regroup thymic clusters
#Similar cluster are annotate as one
Idents(T.Seurat.thymus) <- "integrated_snn_res.1.8"
T.Seurat.thymus@meta.data$manualclusters = "nothing"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "22"),]$manualclusters = "22"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "21"),]$manualclusters = "21"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = c("20","18","14")),]$manualclusters = "20,18,14"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = c("8","2","3","23")),]$manualclusters = "8,2,3,23"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "6"),]$manualclusters = "6"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "7"),]$manualclusters = "7"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = c("10","16")),]$manualclusters = "10,16"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "17"),]$manualclusters = "17"

Splenic clusters :

#Look at differentiation markers on splenic clusters
DotPlot(T.Seurat.spleen, features = c("Aes","Anxa1","Ifng","Itgal","Foxp3","S1pr1","Sell","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme_dark(base_size = 14) + coord_flip()

#Regroup splenic clusters
#Similar cluster are annotate as one
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
T.Seurat.spleen@meta.data$manualclusters = "nothing"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "4"),]$manualclusters = "4"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "1"),]$manualclusters = "1"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "9"),]$manualclusters = "9"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "12"),]$manualclusters = "12"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "11"),]$manualclusters = "11"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "19"),]$manualclusters = "19"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "13"),]$manualclusters = "13"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "17"),]$manualclusters = "17"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = c("10","16")),]$manualclusters = "10,16"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "15"),]$manualclusters = "15"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = c("0","5")),]$manualclusters = "0,5"

Dot plot thymus

Setting thymic cluster order

Idents(T.Seurat.thymus) <- "manualclusters"
T.Seurat.thymus@active.ident <- factor(T.Seurat.thymus@active.ident,levels=c("22","21","20,18,14","8,2,3,23","7","6","10,16","17"))
levels(T.Seurat.thymus)
## [1] "22"       "21"       "20,18,14" "8,2,3,23" "7"        "6"       
## [7] "10,16"    "17"
DotPlot(T.Seurat.thymus, dot.scale = 8,features = c("percent.mito","Bmf","Trp53inp1","Tox2","Cd5","Cd69","Cd27","Rag1","Rag2","Cd4","Cd8a","Cd8b1","Mki67","Cdk1","Ptcra","Il2ra","Cd34")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + coord_flip()+ theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55"))

Dot plot spleen

Setting splenic cluster order

Idents(T.Seurat.spleen) <- "manualclusters"
T.Seurat.spleen@active.ident <- factor(T.Seurat.spleen@active.ident,levels=c("10,16","1","4","0,5","12","15","9","17","13","11","19"))
DotPlot(T.Seurat.spleen, dot.scale = 8, features= c("Foxp3","Aes","Anxa1","Gzma","Ccl5","Cxcr3","Sell","S1pr1","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()

Cluster Identification

General Identification markers

Idents(T.Seurat) <- "integrated_snn_res.1.8"
DefaultAssay(T.Seurat) <- "RNA"
#markerspleen <- FindAllMarkers(T.Seurat)

Detailed identification

Cluster 0

Idents(T.Seurat) <- "integrated_snn_res.1.8"
FeaturePlot(T.Seurat, features = c("adt_CD4","Sell","Cd8b1"),ncol = 3,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 0 seems to contain naive SP4 cells (CD4+, Cd8- and CD62L-)

Cluster 1

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Sell"),ncol = 4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 1 seems to contain CD8 naive T cells (CD4-, Cd8+ and CD62L-)

Cluster 2

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Sell"),ncol = 4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 2 seems to contain DP cells (CD4+, CD8+, CD62L-)

Cluster 3

Cluster 4

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Sell"),ncol = 4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 4 seems to contain CD8 naive T cells (CD4-, Cd8+, and CD62L-)

Cluster 5

FeaturePlot(T.Seurat, features = c("adt_CD4","Sell","Cd8b1"),ncol = 3,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 5 seems to contain naive SP4 cells (CD4+, Cd8- and CD62L-)

Cluster 6

FeaturePlot(T.Seurat, features = c("percent.mito"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"), pt.size = 1)

Cluster 6 seems to contain dying cells

Cluster 7

FeaturePlot(T.Seurat, features = c("Cd69","Cd5","Satb1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black")) #marker of TCR activation 

Seems to contain cells going from DP to SP between thymus and spleen

Cluster 8

Cluster 9

FeaturePlot(T.Seurat, features = c("Cd4","adt_CD4"))

VlnPlot(T.Seurat.spleen, features = c("Sell","Ccr7","Il7r","Cxcr3"),ncol=2) # Cxcr3 high on effector

Seems to contain CD4 eff (Cd4+, Sell-, Ccr7-, Cd127-)

Cluster 10

Cluster 11

FeaturePlot(T.Seurat, features = c("Cd8b1","Sell","Ccl5","adt_CD4"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Trac","Trbc1","Trdc","Tcrg-C1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Ly6c2","Nkg7"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat.spleen, features = c("Sell","Ccr7","Il7r"))

Cluster 11 Seems to contain CD8 mem cells & seem to contain Tgd cells & Ly6c2+

Cluster 12

FeaturePlot(T.Seurat, features = c("adt_CD4","Sell","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeatureScatter(object = T.Seurat, feature1 = "adt_CD4", feature2 = "CD8", cells = colnames(subset(T.Seurat, idents = "0")), slot = "data")

Cluster 12 seems to contain naive SP4 cells (CD4+, Cd8- and CD62L -)

Cluster 13

plot1 <- DotPlot(cluster13, dot.scale = 10, features= c("Foxp3","Aes","Anxa1","Gzma","Ccl5","Cxcr3","Sell","S1pr1","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()
plot2 <- DotPlot(cluster13, dot.scale = 10, features= unique(top_genes_feature_plot$gene)) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()
grid.arrange(plot1, plot2, ncol=2)

#table(cluster13@meta.data$integrated_snn_res.1)

This cluster is heterogeneous

Cluster 14

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat, features = c("Pcna","Cdk1","Mki67")) #teichmann

Cluster 14 seems to be Dp blast

Cluster 15

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Foxp3","Il2ra"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 15 seems to contain Treg (CD4+, Cd8-, Cd25+, Foxp3+)

Cluster 16

Cluster 17

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd8b1","Trdc","Tcrg-C1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 17 seem to contain Tgd DN (CD4-, Cd8-, TCR D+, TCR G+)

Cluster 18

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat, features = c("Pcna","Cdk1","Mki67")) #teichmann

Dp blast

Cluster 19

FeaturePlot(T.Seurat, features = c("Cd8b1","Sell","Ccl5","Gzma","Klrc1","Ifng","Zeb2","Ly6c2"),ncol = 3,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

# Zeb2 terminally differentiated CTL
VlnPlot(T.Seurat.spleen, features = c("Sell","Ccr7","Il7r"))

Cluster 19 seemsto contain CD8 CTL (CD4-, Cd8+, Ccl5+, Sell-, ccr7-,cd127-) & Ly6c2+

Cluster 20

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat, features = c("Pcna","Cdk1","Mki67")) #teichmann

Seems to be Dp blast

Cluster 21

FeaturePlot(T.Seurat, features = c("Cd8b1","adt_CD4"))

VlnPlot(T.Seurat, features = c("Cd8b1","adt_CD4"))

Cluster 21 seem to contain ISP cells (CD4-, Cd8+)

Cluster 22

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Il2ra"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 22 seems to contain DN T cells (CD4-, Cd8-, Cd25+)

Cluster 23

VlnPlot(T.Seurat, features = c("Cd8b1","adt_CD4"))

VlnPlot(T.Seurat, features = c("Rag1")) #on DP cells mostly (immgen), DP quicient or DP blast (Teichman)

Seems to be Dp small (Cd4+,Cd8+,Rag1+)

MYC vs WT

Radar plot

#check genotype proportion in each spleen clusters

df <- as.data.frame(as.data.frame.matrix(t(prop.table(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$manualclusters),1)*100)))
df$cluster = rownames(df)
df2<-as.data.frame(t(cbind(rep(60,11),rep(0,11),df)[,1:6]))
rownames(df2[1:2,]) <- c("60","0")

#order data frame
df2 <- df2[c("10,16","19","11","13","17","9","15","12","0,5","4","1")]

radarchart(df2, cglcol="grey", cglty=1 ,cglwd=0.8, vlcex=0.8, pcol=c("#FF99FF","coral1","cyan3","chartreuse3") , plwd=3, plty=1 ,caxislabels=paste(seq(from = 0,to = 60,by = 15),"%"), axislabcol = "grey40", axistype = 0)

#check genotype proportion in each thymic cluster
df <-  as.data.frame(as.data.frame.matrix(t(prop.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters),1)*100)))
df$cluster = rownames(df)
df2<-as.data.frame(t(cbind(rep(65,8),rep(0,8),df)[,1:6]))
rownames(df2[1:2,]) <- c("65","0")

#order
df2 <- df2[c("22","17","10,16","6","7","8,2,3,23","20,18,14","21")]


radarchart(df2, cglcol="grey", cglty=1,caxislabels=paste(seq(0,70,17.5),"%"), axistype = 0,axislabcol="grey40", cglwd=0.8, vlcex=0.8, pcol=c("#FF99FF","coral1","cyan3","chartreuse3") , plwd=3, plty=1 )

### Proportion bar plot

#thymic proportions
datathym <- data.frame(prop.table(t(prop.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters),1)),1)*100)
#order cluster level
datathym$Var1 <- factor(datathym$Var1, levels = c("22","21","20,18,14","8,2,3,23","7","6","10,16","17"))

cellnumber <- data.frame(colSums(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters)) )
cellnumber$cluster <- rownames(cellnumber)
row_order <- c("22","21","20,18,14","8,2,3,23","6","7","17","10,16")
cellnumber <- cellnumber[row_order,]

Cluster <- datathym$Var1
HTO <- datathym$Var2
Percentage <- datathym$Freq
text <- cellnumber$colSums.table.T.Seurat.thymus.meta.data.HTO..T.Seurat.thymus.meta.data.manualclusters..

cols <- c("Myc- PTEN- thymus" = "#FF99FF", "MYC- thymus" = "coral1", "PTEN- thymus" = "cyan3", "WT thymus" = "chartreuse3")

ggplot(datathym, aes(fill=HTO, y=Percentage, x=Cluster)) + 
    geom_bar(position="stack", stat="identity", width=0.7)+
   xlab("Thymic Clusters")+ylab("Percentage")+ theme(legend.position="bottom")+ scale_fill_manual(values =cols, labels=c("Myc Pten","Myc","Pten","WT"))+theme_light()+geom_hline(yintercept=c(25,50,75), linetype="dashed", color = "grey60")+ annotate("text", x = c(1,2,3,4,5,6,7,8), y=103, label = c(paste0(text)))

#splenic proportions
Idents(T.Seurat.spleen) <- "manualclusters"
T.Seurat.spleenbar <- subset(T.Seurat.spleen,  idents = c("0,5","9","1","11","19")) #to only keep cluster needed for the plot
data3 <- data.frame(prop.table(t(prop.table(table(T.Seurat.spleenbar@meta.data$HTO,T.Seurat.spleenbar@meta.data$manualclusters),1)),1)*100)

#order cluster level
data3$Var1 <- factor(data3$Var1, levels = c("0,5","9","1","11","19"))

cellnumber <- data.frame(colSums(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$manualclusters)) )
cellnumber$cluster <- rownames(cellnumber)
row_order <-c("0,5","9","1","11","19")
cellnumber <- cellnumber[row_order,]

Cluster <- data3$Var1
HTO <- data3$Var2
Percentage <- data3$Freq
text <- cellnumber$colSums.table.T.Seurat.spleen.meta.data.HTO..T.Seurat.spleen.meta.data.manualclusters..
# Stacked bar plot
cols <- c("Myc- PTEN- spleen" = "#FF99FF", "MYC- spleen" = "coral1", "PTEN- spleen" = "cyan3", "WT spleen" = "chartreuse3")

ggplot(data3, aes(fill=HTO, y=Percentage, x=Cluster)) + 
    geom_bar(position="stack", stat="identity", width=0.7)+
   xlab("Splenic Clusters")+ylab("Percentage")+ theme(legend.position="bottom")+scale_fill_manual(values =cols, labels=c("Myc Pten","Myc","Pten","WT")) +theme_light()+geom_hline(yintercept=c(25,50,75), linetype="dashed", color = "grey60")+ annotate("text", x = c(1,2,3,4,5), y=103, label = c(text))

Differential Gene Expression

CD8

Idents(T.Seurat) <- "integrated_snn_res.1.8"
#DGE between our two CD8 naive clusters
dgecd8_data <- FindMarkers(T.Seurat, ident.1 = "1", ident.2 = "4",logfc.threshold=0)

# bar plot
#add abs value to table
dgecd8_data$abs <- abs(dgecd8_data$avg_logFC) 

dgecd8_data$genename <- rownames(dgecd8_data)
# Select markers for plotting on a Heatmap 
markers.use=subset(dgecd8_data, p_val_adj<1e-50 & abs>0.20)
dfcd8markers <-markers.use[order(markers.use$avg_logFC),]

dfcd8markers$genename <- factor(dfcd8markers$genename, levels = dfcd8markers$genename[order(dfcd8markers$avg_logFC)])
dfcd8markers$logpval <- log10(dfcd8markers$p_val_adj)

ggplot(dfcd8markers, aes(x = dfcd8markers$genename, y = dfcd8markers$avg_logFC, fill = logpval)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              ylim(-1.2,1.2)+
                              labs(title="Try dGE") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5),axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), 
                                    axis.ticks = element_blank()) +
                               scale_fill_gradient2(low='red', mid='orange', high='blue',midpoint = -120, breaks=c(-52,-120,-200),labels=c("-50","-120","-200"))+coord_flip() # Flip axes

#### CD4

#define proportion of genotype in CD4 naive clusters
T.Seurat.spleen@meta.data$manualHTO = "nothing"
Idents(T.Seurat.spleen) <- "MULTI_ID"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "MULTI_ID", idents = c("Spleen-ctrl","Spleen-P")),]$manualHTO = "Spleen-ctrl&P"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "MULTI_ID", idents = c("Spleen-M","Spleen-MP")),]$manualHTO = "Spleen-M&MP"

prop.table(t(prop.table(table(T.Seurat.spleen@meta.data$integrated_snn_res.1.8,T.Seurat.spleen@meta.data$manualHTO),1)),2)*100
##                
##                         0         1 2 3         4         5 6 7 8
##   Spleen-ctrl&P 17.473118 20.257235     94.642857 28.667413      
##   Spleen-M&MP   82.526882 79.742765      5.357143 71.332587      
##                
##                         9        10        11        12        13 14
##   Spleen-ctrl&P 75.000000 25.187970 33.732057 71.000000 60.818713   
##   Spleen-M&MP   25.000000 74.812030 66.267943 29.000000 39.181287   
##                
##                        15        16        17 18        19 20 21 22 23
##   Spleen-ctrl&P 43.016760 36.423841 17.647059    35.256410            
##   Spleen-M&MP   56.983240 63.576159 82.352941    64.743590
#in our CD4 naive clusters (0,5 and 12) the one with most cells from M&MP is 0 and the one with most cells from ctrl&P is 12

Idents(T.Seurat) <- "integrated_snn_res.1.8"
#DGE between 0 and 12
dgecd4_data <- FindMarkers(T.Seurat, ident.1 = "0", ident.2 = "12",logfc.threshold=0)
# bar plot
#add abs value to table
dgecd4_data$abs <- abs(dgecd4_data$avg_logFC) 

dgecd4_data$genename <- rownames(dgecd4_data)
# Select markers for plotting on a Heatmap 
markers.use=subset(dgecd4_data,p_val_adj<1e-10 & abs>0.2)
dfcd4markers <-markers.use[order(markers.use$avg_logFC),]

dfcd4markers$genename <- factor(dfcd4markers$genename, levels = dfcd4markers$genename[order(dfcd4markers$avg_logFC)])
dfcd4markers$logpval <- log10(dfcd4markers$p_val_adj)

ggplot(dfcd4markers, aes(x = dfcd4markers$genename, y = dfcd4markers$avg_logFC, fill = logpval)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              ylim(-1.2,1.2)+
                              labs(title="Try dGE CD4") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5),axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), 
                                    axis.ticks = element_blank()) +
                               scale_fill_gradient2(low='red', mid='orange', high='blue',midpoint = -40, breaks=c(-12,-40,-57),labels=c("-10","-40","-60"))+ coord_flip() # Flip axes

Functional profil analysis (Gene Ontology)

Idents(T.Seurat) <- "integrated_snn_res.1.8"

# get all gene name express in our cells as background
background <- T.Seurat@assays$RNA@meta.features
backgroundrow <- rownames(background)

Naive CD8 T cells

#DGE between our two CD8 naive clusters
#dgecd8_data <- FindMarkers(T.Seurat, ident.1 = "1", ident.2 = "4",logfc.threshold=0)
#upreg_cd8 <- subset(dgecd8_data, avg_logFC>0)
#downreg_cd8 <- subset(dgecd8_data, avg_logFC<0.2 & p_val_adj<1e-50)
#genecomprow <- rownames(downreg_cd8)


#### TO SUPPRESS FOR FINAL
#write.table(genecomprow,file="/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster1v4.txt",sep="\t",quote=F)
genecomprow <- read.table("/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster1v4.txt", sep = "\t")
genecomprow$x = as.character(genecomprow$x)
genecomprow <- genecomprow[,1]
####

CPenrich <- enrichGO(gene= genecomprow, OrgDb = 'org.Mm.eg.db', ont="BP",keyType = "SYMBOL",universe = backgroundrow) # org.Mm.eg.db genome mouse
head (CPenrich)
##                    ID                          Description GeneRatio
## GO:0002181 GO:0002181              cytoplasmic translation     16/51
## GO:0042254 GO:0042254                  ribosome biogenesis     21/51
## GO:0022613 GO:0022613 ribonucleoprotein complex biogenesis     22/51
## GO:0042274 GO:0042274   ribosomal small subunit biogenesis     13/51
## GO:0042255 GO:0042255                    ribosome assembly     13/51
## GO:0000028 GO:0000028     ribosomal small subunit assembly      8/51
##              BgRatio       pvalue     p.adjust       qvalue
## GO:0002181  79/13400 2.587342e-24 1.495484e-21 1.342694e-21
## GO:0042254 263/13400 4.286807e-23 1.238887e-20 1.112314e-20
## GO:0022613 397/13400 9.509083e-21 1.832083e-18 1.644904e-18
## GO:0042274  61/13400 3.841622e-20 5.551144e-18 4.983999e-18
## GO:0042255  66/13400 1.180651e-19 1.364832e-17 1.225391e-17
## GO:0000028  17/13400 5.863805e-16 5.648799e-14 5.071677e-14
##                                                                                                                                    geneID
## GO:0002181                                Rplp0/Rpl18a/Rps28/Rpl17/Rpl39/Rps2/Rps23/Rpl10a/Rpl15/Rplp1/Rpl8/Rpl18/Rpl36/Rpl24/Rps29/Rpl26
## GO:0042254       Rps19/Rplp0/Rps5/Rps28/Rps24/Rps7/Rps6/Rps2/Rpl23a/Rps16/Rpl3/Rpsa/Rps8/Rpl10a/Rpl12/Rps14/Rpl14/Rps10/Rps15/Rpl24/Rpl26
## GO:0022613 Rps19/Rplp0/Rps5/Rps28/Rps24/Rps7/Rps6/Rps2/Rpl23a/Rps16/Rpl3/Rpsa/Rps8/Rps23/Rpl10a/Rpl12/Rps14/Rpl14/Rps10/Rps15/Rpl24/Rpl26
## GO:0042274                                                        Rps19/Rps5/Rps28/Rps24/Rps7/Rps6/Rps2/Rps16/Rpsa/Rps8/Rps14/Rps10/Rps15
## GO:0042255                                                     Rps19/Rplp0/Rps5/Rps28/Rps2/Rpl23a/Rpl3/Rpsa/Rpl12/Rps14/Rps10/Rps15/Rpl24
## GO:0000028                                                                                   Rps19/Rps5/Rps28/Rps2/Rpsa/Rps14/Rps10/Rps15
##            Count
## GO:0002181    16
## GO:0042254    21
## GO:0022613    22
## GO:0042274    13
## GO:0042255    13
## GO:0000028     8
dotplot(CPenrich, showCategory=15,color = "p.adjust",x="count") #+ coord_flip()+theme(axis.text.x = element_text(angle = 90, hjust = 1))

emapplot(CPenrich, showCategory = 50)

Naive CD4 T cells

#DGE between our two most control and Myd del CD4 naive clusters
#dgecd4_data <- FindMarkers(T.Seurat, ident.1 = "0", ident.2 = "12",logfc.threshold=0)
#downreg_cd4 <- subset(dgecd4_data, avg_logFC<0& p_val_adj<1e-20)
#genecomprow <- rownames(downreg_cd4)


#### TO SUPPRESS FOR FINAL
#write.table(genecomprow,file="/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster0vs12.txt",sep="\t",quote=F)
genecomprow <- read.table("/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster0vs12.txt", sep = "\t")
genecomprow$x = as.character(genecomprow$x)
genecomprow <- genecomprow[,1]
####


CPenrich <- enrichGO(gene= genecomprow, OrgDb = 'org.Mm.eg.db', ont="BP",keyType = "SYMBOL",universe = backgroundrow) # org.Mm.eg.db genome mouse

dotplot(CPenrich, showCategory=15,color = "p.adjust",x="count")+ scale_y_discrete(labels=function(x)str_wrap(x, width=40))

eYFP negative investigation

Deciphering what are our eYFP negative cells on effector and memory CD8 T cells

Heatmap :

# On cluster 11 - cd8 memory
C11Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11Ctrl])
C11Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11Pt])
C11MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11MP])
C11M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11M])
#on cluster 19 - cd8 eff term
C19Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19Ctrl])
C19Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19Pt])
C19MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19MP])
C19M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19M])
#on cluster 1
C1Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1Ctrl])
C1Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1Pt])
C1MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1MP])
C1M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1M])


l1 <- c("1","1","1","1","11","11","11","11","19","19","19","19")
l2 <- c("Ctrl","Pten","Myc","MycPten","Ctrl","Pten","Myc","MycPten","Ctrl","Pten","Myc","MycPten")
l3 <- c(mC1Ctrl,mC1Pt,mC1M,mC1MP,mC11Ctrl,mC11Pt,mC11M,mC11MP,mC19Ctrl,mC19Pt,mC19M,mC19MP)

tableauYFP <- data.frame(Cluster = l1, Genotypes =l2) 
tableauYFP <- cbind(tableauYFP,Values = l3)


tableauYFP$Cluster <- factor(tableauYFP$Cluster,levels = c("1","11","19"))
tableauYFP$Genotypes <- factor(tableauYFP$Genotypes,levels = c("MycPten","Myc","Pten","Ctrl"))
ggplot(tableauYFP, aes(x = Cluster, Genotypes)) +
        geom_tile(aes(fill = Values)) +
        scale_fill_gradient2( mid='yellow', high='red',limits=c(0,max(tableauYFP$Values)))+ theme_classic(base_size=20)

eYFP neagtive are coming from Myc and Myc Pten del mice

#DOT plot eyFP and TGD on CD8 effector and memory
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
CD8sub <- subset(T.Seurat.spleen, idents = c("11","19","13"))
Idents(CD8sub) <- "MULTI_ID"
CD8sub@active.ident <- factor(CD8sub@active.ident,levels=c("Spleen-M","Spleen-MP","Spleen-ctrl","Spleen-P"))
levels(CD8sub)
## [1] "Spleen-M"    "Spleen-MP"   "Spleen-ctrl" "Spleen-P"
DotPlot(CD8sub, dot.scale = 8,features = c("Tcrg-C1","Trdc","Trbc2","Trac","eYFP") ) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red")+ ggtitle("CD8 memory and effector clusters")

eyFP negative are coming from Myc and Myc Pten del mice and are Tgd cells.

Session Info

sessionInfo()
## R version 3.5.3 (2019-03-11)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
## 
## Matrix products: default
## BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.18.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] parallel  stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] org.Mm.eg.db_3.7.0     AnnotationDbi_1.44.0   IRanges_2.16.0        
##  [4] S4Vectors_0.20.1       Biobase_2.42.0         BiocGenerics_0.28.0   
##  [7] knitr_1.23             RColorBrewer_1.1-2     magrittr_1.5          
## [10] dplyr_0.8.1            stringr_1.4.0          ggthemes_4.2.0        
## [13] clusterProfiler_3.10.1 enrichplot_1.2.0       fmsb_0.6.3            
## [16] gridExtra_2.3          kableExtra_1.1.0       plotly_4.9.0          
## [19] ggplot2_3.1.1          Seurat_3.0.1          
## 
## loaded via a namespace (and not attached):
##   [1] fastmatch_1.1-0     plyr_1.8.4          igraph_1.2.4.1     
##   [4] lazyeval_0.2.2      splines_3.5.3       BiocParallel_1.16.6
##   [7] listenv_0.7.0       urltools_1.7.3      digest_0.6.19      
##  [10] htmltools_0.3.6     GOSemSim_2.8.0      viridis_0.5.1      
##  [13] GO.db_3.7.0         gdata_2.18.0        memoise_1.1.0      
##  [16] cluster_2.0.9       ROCR_1.0-7          globals_0.12.4     
##  [19] readr_1.3.1         R.utils_2.8.0       prettyunits_1.0.2  
##  [22] colorspace_1.4-1    blob_1.1.1          rvest_0.3.4        
##  [25] ggrepel_0.8.1       xfun_0.7            crayon_1.3.4       
##  [28] jsonlite_1.6        survival_2.44-1.1   zoo_1.8-5          
##  [31] ape_5.3             glue_1.3.1          polyclip_1.10-0    
##  [34] gtable_0.3.0        webshot_0.5.1       UpSetR_1.4.0       
##  [37] future.apply_1.2.0  scales_1.0.0        DOSE_3.8.2         
##  [40] DBI_1.0.0           bibtex_0.4.2        Rcpp_1.0.1         
##  [43] metap_1.1           viridisLite_0.3.0   progress_1.2.2     
##  [46] gridGraphics_0.5-1  reticulate_1.12     bit_1.1-14         
##  [49] europepmc_0.4       rsvd_1.0.0          SDMTools_1.1-221.1 
##  [52] tsne_0.1-3          htmlwidgets_1.3     httr_1.4.0         
##  [55] fgsea_1.8.0         gplots_3.0.1.1      ica_1.0-2          
##  [58] pkgconfig_2.0.2     R.methodsS3_1.7.1   farver_1.1.0       
##  [61] ggplotify_0.0.5     tidyselect_0.2.5    labeling_0.3       
##  [64] rlang_0.3.4         reshape2_1.4.3      munsell_0.5.0      
##  [67] tools_3.5.3         RSQLite_2.1.1       ggridges_0.5.1     
##  [70] evaluate_0.13       yaml_2.2.0          npsurv_0.4-0       
##  [73] bit64_0.9-7         fitdistrplus_1.0-14 caTools_1.17.1.2   
##  [76] purrr_0.3.2         RANN_2.6.1          ggraph_1.0.2       
##  [79] pbapply_1.4-0       future_1.13.0       nlme_3.1-140       
##  [82] R.oo_1.22.0         DO.db_2.9           xml2_1.2.0         
##  [85] compiler_3.5.3      rstudioapi_0.10     png_0.1-7          
##  [88] lsei_1.2-0          tibble_2.1.1        tweenr_1.0.1       
##  [91] stringi_1.4.3       lattice_0.20-38     Matrix_1.2-17      
##  [94] pillar_1.4.0        BiocManager_1.30.4  Rdpack_0.11-0      
##  [97] triebeard_0.3.0     lmtest_0.9-37       data.table_1.12.2  
## [100] cowplot_0.9.4       bitops_1.0-6        irlba_2.3.3        
## [103] gbRd_0.4-11         qvalue_2.14.1       R6_2.4.0           
## [106] KernSmooth_2.23-15  codetools_0.2-16    MASS_7.3-51.4      
## [109] gtools_3.8.1        assertthat_0.2.1    withr_2.1.2        
## [112] sctransform_0.2.0   hms_0.4.2           grid_3.5.3         
## [115] tidyr_0.8.3         rmarkdown_1.12      rvcheck_0.1.8      
## [118] Rtsne_0.15          ggforce_0.2.2       base64enc_0.1-3
LS0tCnRpdGxlOiAiRXhwZXJpbWVudF9hbmFseXNpcyIKYXV0aG9yOiAiRGVscGhpbmUgUG90aWVyIC8gTWF0aGlzIE5vemFpcyAvIFNhcmFuIFBhbmthZXciCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTgwMHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKfQo8L3N0eWxlPgoKYGBge3IgZ2xvYmFsLW9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbGlnbiA9ICdjZW50ZXInKQpgYGAKCgojdG8gZG8gYmVmb3JlIHB1Ymxpc2gKYGBge3J9CiNyZW1ldHRyZSBsaWduZSBkZSBjb2RlIGdlbmVyYWwgaWRlbnRpZmljYXRpb24gKHRyb3AgbG9uZyBhIGNhbGN1bCBwb3VyIGxlcyB0ZXN0IGRlIGtuaXQpICsgcmVtZXR0cmUgcG91ciBjbHVzdGVyIDEzIGRldXggcHJlbWllcmUgbGlnbmUgbGlzdC4uCgojY2x1c3RlciAzIERQIHNtYWxsLCA4LDEwLDE2CiMxMSByZWZhaXJlIHRleHQgbWFycXVldXIKI3JlZmFpcmUgY2x1c3RlciAxMyBhdmVjIGFubm90IG9uZSBub3RlIHBvdXIgcGV0aXQgaWRkZW50aWYgZGVzIHBvcAojRFAgYmxhc3QgcHV0IGNlbGwgY3ljbGUgdW1hcCA/IGRhbnMgbGUgZmljaGllciBteWNfcHRlbl9wYXBlciAtLT4gcmVwb3J0IG15Y3B0ZW4uLmNjY2FpbnRlZ3JhdGlvbl9tb2RpZgoKI3Jldm9pciB0aXRyZSBwYXJ0aWUgZW4gZm9uY3Rpb24gZHUgcGFwaWVyCiNyZWZhaXJlIGRvY2tlciBlbiB2ZXJpZmlhbnQgcXVlIHRvdXQgbGVzIGxpYnJhaXJpZXMgbmVjZXNzYWlyZSBzb250IGRvd2xvYW5kIGRlZGFucwoKI3ZlcmlmIHRvdXQgY29tbSBzb250IGJlaW4gZW4gYW5nbGFpcwoKI0NEOCB2cyBDRDQgcmVtZXR0cmUgbGVzIGNhbGN1bCBkZSBmaW4gbWFya2VyIHBvdXIgbGUgZmluYWwgZXQgcGFzIGxlIGxvYWQgZmljaGllciBxdWkgZXN0IGxhIHBvcnUgZ2FnbmVyIGR1IHRlbXBzCgojY2hhbmdlIG91dHB1dCBwYXRoCmBgYAoKCgpgYGB7ciBlbnZfbG9hZGluZywgaW5jbHVkZT1GQUxTRX0KIyBMb2FkIHBhY2thZ2VzLCBkYXRhIGFuZCBmdW5jdGlvbnMKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCiNpbnN0YWxsLnBhY2thZ2VzKCJmbXNiIikKbGlicmFyeShmbXNiKQojQmlvY01hbmFnZXI6Omluc3RhbGwoImNsdXN0ZXJQcm9maWxlciIpCiNCaW9jTWFuYWdlcjo6aW5zdGFsbCgiZW5yaWNocGxvdCIpCmxpYnJhcnkoZW5yaWNocGxvdCkKbGlicmFyeShjbHVzdGVyUHJvZmlsZXIpCiNsaWJyYXJ5KGdncmVwZWwpCiNpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5ciIpCiNsaWJyYXJ5KCJ0aWR5ciIpCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3RoZW1lcyIpCmxpYnJhcnkoZ2d0aGVtZXMpCiNsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShzdHJpbmdyKQoKCiNQYXRoIHRvIHRoZSBhbmFseXNpcyBmb2xkZXIKV09SS1NQQUNFIDwtICIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL015Y19yZXBvLyIKIyBQYXRoIHRvIHRoZSBmb2xkZXIgY29udGFpbmluZyBzY3JpcHRzIHVzZWQgaW4gdGhlIGFuYWx5c2lzCkNXRCA8LSAiL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvRnVuY3Rpb25fZGVscGhpbmUvIiAKIyBMb2FkIHRoZSBSIHNjcmlwdHMgY29udGFpbmluZyB0aGUgZnVuY3Rpb25zIHVzZWQgaW4gdGhlIGFuYWx5c2lzCnNvdXJjZShwYXN0ZShDV0QsICJXb3JrZmxvd19mdW5jdGlvbnNfUzMuUiIsIHNlcD0iLyIpKQojICBQYXRoIHRvIHRoZSBmb2xkZXIgdGhhdCB3aWxsIGNvbnRhaW4gb3V0cHV0IG9iamVjdHMKT1VUUFVUX1BBVEggPC0gKCIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL091dHB1dF9yZXBvLyIpCiMgU2V0IHRoZSByYW5kb20gbnVtYmVyIHNlZWQKc2V0LnNlZWQoMTIzNCkKIyBSZXNvbHV0aW9uIHBhcmFtZXRlciBmb3IgU2V1cmF0IGNsdXN0ZXJpbmcKUkVTT0xVVElPTiA8LSAxCmBgYAoKYGBge3IscmVzdWx0cz0nYXNpcyd9CiNsb2FkaW5nIGZpbmFsIG9iamVjdCBvYnRhaW4gd2l0aCBFeHBlcmltZW50X3ByZXByb2Nlc3NpbmcKU0FNUExFMSA8LSAiMTgxMDMxIgpTQU1QTEUyIDwtICIxOTAyMTEiCgppZighIGZpbGUuZXhpc3RzKHBhc3RlMChPVVRQVVRfUEFUSCwgIlQtU2V1cmF0LW1lcmdlZF9jbGVhbi1zdWJzZXQiLCIuUm9iaiIpKSl7CnByaW50KCJZb3Ugc2hvdWxkIHN0YXJ0IHdpdGggRXhwZXJpbWVudF9wcmVwcm9jZXNzaW5nLlJtZCBvciBkb3dsb2FkIG91ciBmaW5hbCBvYmplY3QgJ1QtU2V1cmF0LW1lcmdlZF9jbGVhbi1zdWJzZXQuUm9iaicgIikKZG8gPC0gRkFMU0UKfWVsc2V7IApwcmludCAoIllvdSBhcmUgc3RhcnRpbmcgYW5hbHlzaXMgb2Ygb3VyIGZpbmFsIFNldXJhdCBvYmplY3QiKQpsb2FkKHBhc3RlMChPVVRQVVRfUEFUSCwgIlQtU2V1cmF0LW1lcmdlZF9jbGVhbi1zdWJzZXQiLCIuUm9iaiIpKQpkbyA8LSBUUlVFCn0KCmBgYAoKCmBgYHthc2lzLCBldmFsPShkbyA9PSBUUlVFICksIGVjaG89VFJVRX0KIyBDcmVhdGluZyB0aXNzdWUgc3Vic2V0CiMjIFRoeW11cyBzdWJzZXQKYGBgCgpgYGB7cixldmFsPShkbyA9PSBUUlVFICl9CklkZW50cyhULlNldXJhdCkgPC0gIkhUTyIKVC5TZXVyYXQudGh5bXVzIDwtIHN1YnNldChULlNldXJhdCwgaWRlbnRzID0gYygiTXljLSBQVEVOLSB0aHltdXMiLCJNWUMtIHRoeW11cyIsIlBURU4tIHRoeW11cyIsIldUIHRoeW11cyIpKQphIDwtIHQobWFyZ2luLnRhYmxlKHRhYmxlKFQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCksMikpClQuU2V1cmF0LnNwbGVlbiA8LSBzdWJzZXQoVC5TZXVyYXQsIGlkZW50cyA9IGMoIk15Yy0gUFRFTi0gc3BsZWVuIiwiTVlDLSBzcGxlZW4iLCJQVEVOLSBzcGxlZW4iLCJXVCBzcGxlZW4iKSkKYiA8LSB0KG1hcmdpbi50YWJsZSh0YWJsZShULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJEhUTyxULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjgpLDIpKQpjIDwtIHQoKGEvKGErYikqMTAwKSkKYwojVGh5bWljIHBvcHVsYXRpb25zCnRoeW11cy5jbHVzdGVycyA8LSByb3duYW1lcyhhcy5kYXRhLmZyYW1lKGNbd2hpY2goY1ssMV0+MjUpLF0pKQpJZGVudHMoVC5TZXVyYXQudGh5bXVzKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKVC5TZXVyYXQudGh5bXVzIDwtIHN1YnNldChULlNldXJhdC50aHltdXMsIGlkZW50cyA9IHRoeW11cy5jbHVzdGVycykKRGltUGxvdChULlNldXJhdC50aHltdXMpCmBgYAoKYGBge2FzaXMsIGV2YWw9KGRvID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBTcGxlZW4gc3Vic2V0CmBgYAoKCmBgYHtyfQojU3BsZWVuIHBvcHVsYXRpb25zCmFzLmRhdGEuZnJhbWUoMTAwLWNbd2hpY2goY1ssMV08NzUpLF0pCnNwbGVlbi5jbHVzdGVycyA8LSByb3duYW1lcyhhcy5kYXRhLmZyYW1lKGNbd2hpY2goY1ssMV08NzUpLF0pKQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKVC5TZXVyYXQuc3BsZWVuIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sIGlkZW50cyA9IHNwbGVlbi5jbHVzdGVycykKRGltUGxvdChULlNldXJhdC5zcGxlZW4pCmBgYAoKIyBNYW51YWwgY2x1c3RlcmluZwpCYXNlZCBvbiBzZXZlcmFsIG1hcmtlcnMgd2UgYXJlIGFkanVzdGluZyBvdXIgY2x1c3RlcmdpbmcsIHNpbWlsYXIgY2x1c3RlciBhcmUgdGhlbiBhbm5vdGF0ZSBhcyBvbmUuCgpUaHltaWMgY2x1c3RlcnMgOgpgYGB7cn0KI0xvb2sgYXQgZGlmZmVyZW50aWF0aW9uIG1hcmtlcnMgb24gdGh5bWljIGNsdXN0ZXJzCkRvdFBsb3QoVC5TZXVyYXQudGh5bXVzLCBmZWF0dXJlcyA9IGMoInBlcmNlbnQubWl0byIsIkJtZiIsIlRycDUzaW5wMSIsIlRveDIiLCJDZDUiLCJDZDY5IiwiQ2QyNyIsIlJhZzEiLCJSYWcyIiwiQ2Q0IiwiQ2Q4YSIsIkNkOGIxIiwiVWNobDMiLCJNa2k2NyIsIkNkazEiLCJQdGNyYSIsIklsMnJhIiwiQ2QzNCIpKSArIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobG93ID0gInN0ZWVsYmx1ZSIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAicmVkIikgKyB0aGVtZV9kYXJrKGJhc2Vfc2l6ZSA9IDE0KSArIGNvb3JkX2ZsaXAoKQoKI1JlZ3JvdXAgdGh5bWljIGNsdXN0ZXJzCiNTaW1pbGFyIGNsdXN0ZXIgYXJlIGFubm90YXRlIGFzIG9uZQpJZGVudHMoVC5TZXVyYXQudGh5bXVzKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyA9ICJub3RoaW5nIgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMjIiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjIyIgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMjEiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjIxIgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSBjKCIyMCIsIjE4IiwiMTQiKSksXSRtYW51YWxjbHVzdGVycyA9ICIyMCwxOCwxNCIKVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gYygiOCIsIjIiLCIzIiwiMjMiKSksXSRtYW51YWxjbHVzdGVycyA9ICI4LDIsMywyMyIKVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjYiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjYiClQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICI3IiksXSRtYW51YWxjbHVzdGVycyA9ICI3IgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSBjKCIxMCIsIjE2IikpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTAsMTYiClQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxNyIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTciCmBgYAoKU3BsZW5pYyBjbHVzdGVycyA6CmBgYHtyfQoKI0xvb2sgYXQgZGlmZmVyZW50aWF0aW9uIG1hcmtlcnMgb24gc3BsZW5pYyBjbHVzdGVycwpEb3RQbG90KFQuU2V1cmF0LnNwbGVlbiwgZmVhdHVyZXMgPSBjKCJBZXMiLCJBbnhhMSIsIklmbmciLCJJdGdhbCIsIkZveHAzIiwiUzFwcjEiLCJTZWxsIiwiQ2NyNyIsIlRyZGMiLCJUY3JnLUM0IiwiVGNyZy1DMiIsIlRjcmctQzEiLCJUcmJjMiIsIlRyYmMxIiwiVHJhYyIsIkNkOGIxIiwiQ2Q0IikpICsgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAic3RlZWxibHVlIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiKSArIHRoZW1lX2RhcmsoYmFzZV9zaXplID0gMTQpICsgY29vcmRfZmxpcCgpCgojUmVncm91cCBzcGxlbmljIGNsdXN0ZXJzCiNTaW1pbGFyIGNsdXN0ZXIgYXJlIGFubm90YXRlIGFzIG9uZQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyA9ICJub3RoaW5nIgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiNCIpLF0kbWFudWFsY2x1c3RlcnMgPSAiNCIKVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjEiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjEiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICI5IiksXSRtYW51YWxjbHVzdGVycyA9ICI5IgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTIiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjEyIgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTEiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjExIgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTkiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjE5IgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTMiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjEzIgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMTciKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjE3IgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSBjKCIxMCIsIjE2IikpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTAsMTYiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxNSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTUiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9IGMoIjAiLCI1IikpLF0kbWFudWFsY2x1c3RlcnMgPSAiMCw1IgpgYGAKCgojIyBEb3QgcGxvdCB0aHltdXMKClNldHRpbmcgdGh5bWljIGNsdXN0ZXIgb3JkZXIgCmBgYHtyfQpJZGVudHMoVC5TZXVyYXQudGh5bXVzKSA8LSAibWFudWFsY2x1c3RlcnMiClQuU2V1cmF0LnRoeW11c0BhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKFQuU2V1cmF0LnRoeW11c0BhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIjIyIiwiMjEiLCIyMCwxOCwxNCIsIjgsMiwzLDIzIiwiNyIsIjYiLCIxMCwxNiIsIjE3IikpCmxldmVscyhULlNldXJhdC50aHltdXMpCmBgYAoKYGBge3J9CkRvdFBsb3QoVC5TZXVyYXQudGh5bXVzLCBkb3Quc2NhbGUgPSA4LGZlYXR1cmVzID0gYygicGVyY2VudC5taXRvIiwiQm1mIiwiVHJwNTNpbnAxIiwiVG94MiIsIkNkNSIsIkNkNjkiLCJDZDI3IiwiUmFnMSIsIlJhZzIiLCJDZDQiLCJDZDhhIiwiQ2Q4YjEiLCJNa2k2NyIsIkNkazEiLCJQdGNyYSIsIklsMnJhIiwiQ2QzNCIpKSArIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobG93ID0gInN0ZWVsYmx1ZSIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAicmVkIikgKyBjb29yZF9mbGlwKCkrIHRoZW1lKAogIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmV5NjUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiksCiAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMC41LCBsaW5ldHlwZSA9ICdzb2xpZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gImdyZXk1NSIpKQpgYGAKCiMjIERvdCBwbG90IHNwbGVlbgoKU2V0dGluZyBzcGxlbmljIGNsdXN0ZXIgb3JkZXIgCmBgYHtyfQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAibWFudWFsY2x1c3RlcnMiClQuU2V1cmF0LnNwbGVlbkBhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKFQuU2V1cmF0LnNwbGVlbkBhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIjEwLDE2IiwiMSIsIjQiLCIwLDUiLCIxMiIsIjE1IiwiOSIsIjE3IiwiMTMiLCIxMSIsIjE5IikpCmBgYAoKYGBge3J9CkRvdFBsb3QoVC5TZXVyYXQuc3BsZWVuLCBkb3Quc2NhbGUgPSA4LCBmZWF0dXJlcz0gYygiRm94cDMiLCJBZXMiLCJBbnhhMSIsIkd6bWEiLCJDY2w1IiwiQ3hjcjMiLCJTZWxsIiwiUzFwcjEiLCJDY3I3IiwiVHJkYyIsIlRjcmctQzQiLCJUY3JnLUMyIiwiVGNyZy1DMSIsIlRyYmMyIiwiVHJiYzEiLCJUcmFjIiwiQ2Q4YjEiLCJDZDQiKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgdGhlbWUoCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk2NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gJ3NvbGlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTU1IikpICsgY29vcmRfZmxpcCgpCmBgYAoKCiMgQ2x1c3RlciBJZGVudGlmaWNhdGlvbgojIyBHZW5lcmFsIElkZW50aWZpY2F0aW9uIG1hcmtlcnMKYGBge3J9CklkZW50cyhULlNldXJhdCkgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCkRlZmF1bHRBc3NheShULlNldXJhdCkgPC0gIlJOQSIKI21hcmtlcnNwbGVlbiA8LSBGaW5kQWxsTWFya2VycyhULlNldXJhdCkKYGBgCgojIyBEZXRhaWxlZCBpZGVudGlmaWNhdGlvbiB7LnRhYnNldCAudGFic2V0LWZhZGV9CiMjIyBDbHVzdGVyIDAKYGBge3IsZmlnLndpZHRoID0gMTUsIGZpZy5oZWlnaHQgPSA0fQpJZGVudHMoVC5TZXVyYXQpIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiU2VsbCIsIkNkOGIxIiksbmNvbCA9IDMsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q0IiwiQ2Q4YjEiKSxibGVuZCA9IFQsCmJsZW5kLnRocmVzaG9sZD0gMC40LGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpDbHVzdGVyIDAgc2VlbXMgdG8gY29udGFpbiBuYWl2ZSBTUDQgY2VsbHMgKENENCssIENkOC0gYW5kIENENjJMLSkKCiMjIyBDbHVzdGVyIDEKYGBge3IsZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiLCJTZWxsIiksbmNvbCA9IDQsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q0IiwiQ2Q4YjEiKSxibGVuZCA9IFQsCmJsZW5kLnRocmVzaG9sZD0gMC40LGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpDbHVzdGVyIDEgc2VlbXMgdG8gY29udGFpbiBDRDggbmFpdmUgVCBjZWxscyAoQ0Q0LSwgQ2Q4KyBhbmQgQ0Q2MkwtKQoKIyMjIENsdXN0ZXIgMgpgYGB7cixmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJDZDQiLCJDZDhiMSIsIlNlbGwiKSxuY29sID0gNCxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDQiLCJDZDhiMSIpLGJsZW5kID0gVCwKYmxlbmQudGhyZXNob2xkPSAwLjQsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCgpDbHVzdGVyIDIgc2VlbXMgdG8gY29udGFpbiBEUCBjZWxscyAoQ0Q0KywgQ0Q4KywgQ0Q2MkwtKQoKIyMjIENsdXN0ZXIgMwoKIyMjIENsdXN0ZXIgNApgYGB7cixmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJDZDQiLCJDZDhiMSIsIlNlbGwiKSxuY29sID0gNCxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDQiLCJDZDhiMSIpLGJsZW5kID0gVCwKYmxlbmQudGhyZXNob2xkPSAwLjQsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCkNsdXN0ZXIgNCBzZWVtcyB0byBjb250YWluIENEOCBuYWl2ZSBUIGNlbGxzIChDRDQtLCBDZDgrLCBhbmQgQ0Q2MkwtKQoKIyMjIENsdXN0ZXIgNQpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJTZWxsIiwiQ2Q4YjEiKSxuY29sID0gMyxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q0IiwiQ2Q4YjEiKSxibGVuZCA9IFQsCmJsZW5kLnRocmVzaG9sZD0gMC40LGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpDbHVzdGVyIDUgc2VlbXMgdG8gY29udGFpbiBuYWl2ZSBTUDQgY2VsbHMgKENENCssIENkOC0gYW5kIENENjJMLSkKCiMjIyBDbHVzdGVyIDYKYGBge3J9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoInBlcmNlbnQubWl0byIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSwgcHQuc2l6ZSA9IDEpCmBgYApDbHVzdGVyIDYgc2VlbXMgdG8gY29udGFpbiBkeWluZyBjZWxscwoKIyMjIENsdXN0ZXIgNwpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkNkNjkiLCJDZDUiLCJTYXRiMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkgI21hcmtlciBvZiBUQ1IgYWN0aXZhdGlvbiAKYGBgClNlZW1zIHRvIGNvbnRhaW4gY2VsbHMgZ29pbmcgZnJvbSBEUCB0byBTUCBiZXR3ZWVuIHRoeW11cyBhbmQgc3BsZWVuCgojIyMgQ2x1c3RlciA4CgojIyMgQ2x1c3RlciA5CmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkNkNCIsImFkdF9DRDQiKSkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAxNn0KVmxuUGxvdChULlNldXJhdC5zcGxlZW4sIGZlYXR1cmVzID0gYygiU2VsbCIsIkNjcjciLCJJbDdyIiwiQ3hjcjMiKSxuY29sPTIpICMgQ3hjcjMgaGlnaCBvbiBlZmZlY3RvcgpgYGAKU2VlbXMgdG8gY29udGFpbiBDRDQgZWZmIChDZDQrLCBTZWxsLSwgQ2NyNy0sIENkMTI3LSkKCiMjIyBDbHVzdGVyIDEwCmBgYHtyIGNsc3V0ZXIxMH0KCmBgYAoKIyMjIENsdXN0ZXIgMTEKYGBge3IgY2x1c3RlcjExLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkNkOGIxIiwiU2VsbCIsIkNjbDUiLCJhZHRfQ0Q0IiksY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQoKRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiVHJhYyIsIlRyYmMxIiwiVHJkYyIsIlRjcmctQzEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJMeTZjMiIsIk5rZzciKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMTUsIGZpZy5oZWlnaHQgPSA2fQpWbG5QbG90KFQuU2V1cmF0LnNwbGVlbiwgZmVhdHVyZXMgPSBjKCJTZWxsIiwiQ2NyNyIsIklsN3IiKSkKYGBgCgpDbHVzdGVyIDExIFNlZW1zIHRvIGNvbnRhaW4gQ0Q4IG1lbSBjZWxscyAmIHNlZW0gdG8gY29udGFpbiBUZ2QgY2VsbHMgJiBMeTZjMisKCiMjIyBDbHVzdGVyIDEyCmBgYHtyIGNsdXN0ZXIxMn0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIlNlbGwiLCJDZDhiMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKRmVhdHVyZVNjYXR0ZXIob2JqZWN0ID0gVC5TZXVyYXQsIGZlYXR1cmUxID0gImFkdF9DRDQiLCBmZWF0dXJlMiA9ICJDRDgiLCBjZWxscyA9IGNvbG5hbWVzKHN1YnNldChULlNldXJhdCwgaWRlbnRzID0gIjAiKSksIHNsb3QgPSAiZGF0YSIpCmBgYApDbHVzdGVyIDEyIHNlZW1zIHRvIGNvbnRhaW4gbmFpdmUgU1A0IGNlbGxzIChDRDQrLCBDZDgtIGFuZCBDRDYyTCAtKQoKIyMjIENsdXN0ZXIgMTMKYGBge3IgY2x1c3RlcjEzLGluY2x1ZGU9RkFMU0V9CiNsaXN0bWFyazEzIDwtIChtYXJrZXJzcGxlZW5bd2hpY2ggKG1hcmtlcnNwbGVlbiRjbHVzdGVyID09ICIxMyIgJiBtYXJrZXJzcGxlZW4kYXZnX2xvZ0ZDID4wKSwgXSkgI2Nob29zZSBnZW5lIG92ZXJleHByZXNzIGluIGNsdXN0ZXIgMTMgY2VsbHMKI2xpc3RtYXJrMTMgPC0gbGlzdG1hcmsxMyRnZW5lCgojT24gSW1nZW4gZ2VuZSBzZXQgOiBJZGVudGlmeSBhcyBDRDggYW5kL29yIE5LVAojIFRyeSB0byBzZWUgaWYgd2UgY2FuIHN1YmRpdmlzZSB0aGlzIGNsdXN0ZXIgdG8gaWRlbnRpZnkgY2xlYXIgcG9wdWxhdGlvbgojY2x1c3RlciBzdWJzZXQgMTMKSWRlbnRzKFQuU2V1cmF0KSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKY2x1c3RlcjEzIDwtIHN1YnNldChULlNldXJhdCwgIGlkZW50cyA9IGMoIjEzIikpCkRlZmF1bHRBc3NheShjbHVzdGVyMTMpIDwtICJSTkEiICMgdG8gYXZvaWQgZXJyb3Igd2hlbiByZSBzdWJzZXRpbmcgaHR0cHM6Ly9naXRodWIuY29tL3NhdGlqYWxhYi9zZXVyYXQvaXNzdWVzLzE1MjgKCiNjbHVzdGVyMTMgPC0gTm9ybWFsaXplRGF0YShjbHVzdGVyMTMsZGlzcGxheS5wcm9ncmVzcyA9IEZBTFNFKQpjbHVzdGVyMTMgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoY2x1c3RlcjEzLCBkby5wbG90ID0gRiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCBkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCgpjbHVzdGVyMTMgPC0gU2NhbGVEYXRhKCBvYmplY3QgPSAgY2x1c3RlcjEzLCAKICAgICAgICAgICAgICAgICAgICAgIGFzc2F5PSJSTkEiLAogICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgI2RvLnNjYWxlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQoKCmNsdXN0ZXIxMyA8LSBSdW5QQ0Eob2JqZWN0ID0gY2x1c3RlcjEzLCBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gY2x1c3RlcjEzKSwgbnBjcyA9IDEwMCwgc2VlZC51c2UgPSAxMjM0LCB2ZXJib3NlID0gRkFMU0UpCiAgCkVsYm93UGxvdChjbHVzdGVyMTMsIG5kaW1zID0gNTAsIHJlZHVjdGlvbiA9ICJwY2EiKQogIAogICMgU2NvcmVyIGxlcyBnZW5lcyBwb3VyIGxlcyBjb21wb3NhbnRlcwpjbHVzdGVyMTMgPC0gUHJvamVjdERpbShvYmplY3QgPSBjbHVzdGVyMTMsCiAgICAgICAgICAgICAgICAgIG5mZWF0dXJlcy5wcmludCA9IDIwLAogICAgICAgICAgICAgICAgICBkaW1zLnByaW50ID0gMToyMCkKICAKY2x1c3RlcjEzIDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gY2x1c3RlcjEzLAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLAogICAgICAgICAgICAgICAgICBkaW1zID0gMToyMCAsIAogICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UpIywgCiAgICAgICAgICAgICAgICAgICNmb3JjZS5yZWNhbGMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgI3JlZHVjdGlvbiA9ICJwY2EiKQogIApjbHVzdGVyMTMgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IGNsdXN0ZXIxMywgCiAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlJOQSIsCiAgICAgICAgICAgICAgICAgIHJlc29sdXRpb24gPSAxLAogICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgIHJhbmRvbS5zZWVkID0gMTIzNCkKICAjVG8gbWFrZSB0aGUgVU1BUAogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiAgY2x1c3RlcjEzIDwtIFJ1blVNQVAob2JqZWN0ID0gY2x1c3RlcjEzLCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToyMCkKICAgCiAgIERpbVBsb3QoY2x1c3RlcjEzKQogICAKICAgbWFyazEzIDwtIEZpbmRBbGxNYXJrZXJzKGNsdXN0ZXIxMykKICAgdG9wX2dlbmVzX2ZlYXR1cmVfcGxvdCA8LSBtYXJrMTMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3Bfbig1LCBhdmdfbG9nRkMpICMgdGFrZSA1IGZpcnN0IGdlbmUgb2YgZWFjaCBjbHVzdGVyCmBgYAoKCmBgYHtyLGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gOH0KcGxvdDEgPC0gRG90UGxvdChjbHVzdGVyMTMsIGRvdC5zY2FsZSA9IDEwLCBmZWF0dXJlcz0gYygiRm94cDMiLCJBZXMiLCJBbnhhMSIsIkd6bWEiLCJDY2w1IiwiQ3hjcjMiLCJTZWxsIiwiUzFwcjEiLCJDY3I3IiwiVHJkYyIsIlRjcmctQzQiLCJUY3JnLUMyIiwiVGNyZy1DMSIsIlRyYmMyIiwiVHJiYzEiLCJUcmFjIiwiQ2Q4YjEiLCJDZDQiKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgdGhlbWUoCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk2NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gJ3NvbGlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTU1IikpICsgY29vcmRfZmxpcCgpCnBsb3QyIDwtIERvdFBsb3QoY2x1c3RlcjEzLCBkb3Quc2NhbGUgPSAxMCwgZmVhdHVyZXM9IHVuaXF1ZSh0b3BfZ2VuZXNfZmVhdHVyZV9wbG90JGdlbmUpKSArIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobG93ID0gInN0ZWVsYmx1ZSIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAicmVkIikgKyB0aGVtZSgKICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JleTY1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMC41LCBsaW5ldHlwZSA9ICJzb2xpZCIpLAogIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAnc29saWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NTUiKSkgKyBjb29yZF9mbGlwKCkKZ3JpZC5hcnJhbmdlKHBsb3QxLCBwbG90MiwgbmNvbD0yKQojdGFibGUoY2x1c3RlcjEzQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMSkKYGBgClRoaXMgY2x1c3RlciBpcyBoZXRlcm9nZW5lb3VzCgojIyMgQ2x1c3RlciAxNApgYGB7cixmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDh9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJDZDQiLCJDZDhiMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDZ9ClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiUGNuYSIsIkNkazEiLCJNa2k2NyIpKSAjdGVpY2htYW5uCmBgYApDbHVzdGVyIDE0IHNlZW1zIHRvIGJlIERwIGJsYXN0CgojIyMgQ2x1c3RlciAxNQpgYGB7ciBjbHVzdGVyMTUsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIkNkNCIsIkZveHAzIiwiSWwycmEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYApDbHVzdGVyIDE1IHNlZW1zIHRvIGNvbnRhaW4gVHJlZyAoQ0Q0KywgQ2Q4LSwgQ2QyNSssIEZveHAzKykKCiMjIyBDbHVzdGVyIDE2CgojIyMgQ2x1c3RlciAxNyAKYGBge3IgY2x1c3RlcjE3LGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIkNkOGIxIiwiVHJkYyIsIlRjcmctQzEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYApDbHVzdGVyIDE3IHNlZW0gdG8gY29udGFpbiBUZ2QgRE4gKENENC0sIENkOC0sIFRDUiBEKywgVENSIEcrKQoKIyMjIENsdXN0ZXIgMTgKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA4fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiUGNuYSIsIkNkazEiLCJNa2k2NyIpKSAjdGVpY2htYW5uCmBgYApEcCBibGFzdAoKIyMjIENsdXN0ZXIgMTkKYGBge3IsIGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gMTJ9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkNkOGIxIiwiU2VsbCIsIkNjbDUiLCJHem1hIiwiS2xyYzEiLCJJZm5nIiwiWmViMiIsIkx5NmMyIiksbmNvbCA9IDMsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQojIFplYjIgdGVybWluYWxseSBkaWZmZXJlbnRpYXRlZCBDVEwKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDZ9ClZsblBsb3QoVC5TZXVyYXQuc3BsZWVuLCBmZWF0dXJlcyA9IGMoIlNlbGwiLCJDY3I3IiwiSWw3ciIpKQpgYGAKCkNsdXN0ZXIgMTkgc2VlbXN0byBjb250YWluIENEOCBDVEwgKENENC0sIENkOCssIENjbDUrLCBTZWxsLSwgY2NyNy0sY2QxMjctKSAmIEx5NmMyKwoKIyMjIENsdXN0ZXIgMjAKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA4fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiUGNuYSIsIkNkazEiLCJNa2k2NyIpKSAjdGVpY2htYW5uCmBgYApTZWVtcyB0byBiZSBEcCBibGFzdAoKIyMjIENsdXN0ZXIgMjEKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDhiMSIsImFkdF9DRDQiKSkKVmxuUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDhiMSIsImFkdF9DRDQiKSkKYGBgCkNsdXN0ZXIgMjEgc2VlbSB0byBjb250YWluIElTUCBjZWxscyAoQ0Q0LSwgQ2Q4KykKCiMjIyBDbHVzdGVyIDIyCmBgYHtyLGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIkNkNCIsIkNkOGIxIiwiSWwycmEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYApDbHVzdGVyIDIyIHNlZW1zIHRvIGNvbnRhaW4gRE4gVCBjZWxscyAoQ0Q0LSwgQ2Q4LSwgQ2QyNSspCgojIyMgQ2x1c3RlciAyMwpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDN9ClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q4YjEiLCJhZHRfQ0Q0IikpClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiUmFnMSIpKSAjb24gRFAgY2VsbHMgbW9zdGx5IChpbW1nZW4pLCBEUCBxdWljaWVudCBvciBEUCBibGFzdCAoVGVpY2htYW4pCmBgYApTZWVtcyB0byBiZSBEcCBzbWFsbCAoQ2Q0KyxDZDgrLFJhZzErKQoKIyMgTVlDIHZzIFdUCiMjIyBSYWRhciBwbG90CmBgYHtyfQojY2hlY2sgZ2Vub3R5cGUgcHJvcG9ydGlvbiBpbiBlYWNoIHNwbGVlbiBjbHVzdGVycwoKZGYgPC0gYXMuZGF0YS5mcmFtZShhcy5kYXRhLmZyYW1lLm1hdHJpeCh0KHByb3AudGFibGUodGFibGUoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyksMSkqMTAwKSkpCmRmJGNsdXN0ZXIgPSByb3duYW1lcyhkZikKZGYyPC1hcy5kYXRhLmZyYW1lKHQoY2JpbmQocmVwKDYwLDExKSxyZXAoMCwxMSksZGYpWywxOjZdKSkKcm93bmFtZXMoZGYyWzE6MixdKSA8LSBjKCI2MCIsIjAiKQoKI29yZGVyIGRhdGEgZnJhbWUKZGYyIDwtIGRmMltjKCIxMCwxNiIsIjE5IiwiMTEiLCIxMyIsIjE3IiwiOSIsIjE1IiwiMTIiLCIwLDUiLCI0IiwiMSIpXQoKcmFkYXJjaGFydChkZjIsIGNnbGNvbD0iZ3JleSIsIGNnbHR5PTEgLGNnbHdkPTAuOCwgdmxjZXg9MC44LCBwY29sPWMoIiNGRjk5RkYiLCJjb3JhbDEiLCJjeWFuMyIsImNoYXJ0cmV1c2UzIikgLCBwbHdkPTMsIHBsdHk9MSAsY2F4aXNsYWJlbHM9cGFzdGUoc2VxKGZyb20gPSAwLHRvID0gNjAsYnkgPSAxNSksIiUiKSwgYXhpc2xhYmNvbCA9ICJncmV5NDAiLCBheGlzdHlwZSA9IDApCgojY2hlY2sgZ2Vub3R5cGUgcHJvcG9ydGlvbiBpbiBlYWNoIHRoeW1pYyBjbHVzdGVyCmRmIDwtICBhcy5kYXRhLmZyYW1lKGFzLmRhdGEuZnJhbWUubWF0cml4KHQocHJvcC50YWJsZSh0YWJsZShULlNldXJhdC50aHltdXNAbWV0YS5kYXRhJEhUTyxULlNldXJhdC50aHltdXNAbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzKSwxKSoxMDApKSkKZGYkY2x1c3RlciA9IHJvd25hbWVzKGRmKQpkZjI8LWFzLmRhdGEuZnJhbWUodChjYmluZChyZXAoNjUsOCkscmVwKDAsOCksZGYpWywxOjZdKSkKcm93bmFtZXMoZGYyWzE6MixdKSA8LSBjKCI2NSIsIjAiKQoKI29yZGVyCmRmMiA8LSBkZjJbYygiMjIiLCIxNyIsIjEwLDE2IiwiNiIsIjciLCI4LDIsMywyMyIsIjIwLDE4LDE0IiwiMjEiKV0KCgpyYWRhcmNoYXJ0KGRmMiwgY2dsY29sPSJncmV5IiwgY2dsdHk9MSxjYXhpc2xhYmVscz1wYXN0ZShzZXEoMCw3MCwxNy41KSwiJSIpLCBheGlzdHlwZSA9IDAsYXhpc2xhYmNvbD0iZ3JleTQwIiwgY2dsd2Q9MC44LCB2bGNleD0wLjgsIHBjb2w9YygiI0ZGOTlGRiIsImNvcmFsMSIsImN5YW4zIiwiY2hhcnRyZXVzZTMiKSAsIHBsd2Q9MywgcGx0eT0xICkKYGBgCiMjIyBQcm9wb3J0aW9uIGJhciBwbG90CmBgYHtyfQojdGh5bWljIHByb3BvcnRpb25zCmRhdGF0aHltIDwtIGRhdGEuZnJhbWUocHJvcC50YWJsZSh0KHByb3AudGFibGUodGFibGUoVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyksMSkpLDEpKjEwMCkKI29yZGVyIGNsdXN0ZXIgbGV2ZWwKZGF0YXRoeW0kVmFyMSA8LSBmYWN0b3IoZGF0YXRoeW0kVmFyMSwgbGV2ZWxzID0gYygiMjIiLCIyMSIsIjIwLDE4LDE0IiwiOCwyLDMsMjMiLCI3IiwiNiIsIjEwLDE2IiwiMTciKSkKCmNlbGxudW1iZXIgPC0gZGF0YS5mcmFtZShjb2xTdW1zKHRhYmxlKFQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGEkbWFudWFsY2x1c3RlcnMpKSApCmNlbGxudW1iZXIkY2x1c3RlciA8LSByb3duYW1lcyhjZWxsbnVtYmVyKQpyb3dfb3JkZXIgPC0gYygiMjIiLCIyMSIsIjIwLDE4LDE0IiwiOCwyLDMsMjMiLCI2IiwiNyIsIjE3IiwiMTAsMTYiKQpjZWxsbnVtYmVyIDwtIGNlbGxudW1iZXJbcm93X29yZGVyLF0KCkNsdXN0ZXIgPC0gZGF0YXRoeW0kVmFyMQpIVE8gPC0gZGF0YXRoeW0kVmFyMgpQZXJjZW50YWdlIDwtIGRhdGF0aHltJEZyZXEKdGV4dCA8LSBjZWxsbnVtYmVyJGNvbFN1bXMudGFibGUuVC5TZXVyYXQudGh5bXVzLm1ldGEuZGF0YS5IVE8uLlQuU2V1cmF0LnRoeW11cy5tZXRhLmRhdGEubWFudWFsY2x1c3RlcnMuLgoKY29scyA8LSBjKCJNeWMtIFBURU4tIHRoeW11cyIgPSAiI0ZGOTlGRiIsICJNWUMtIHRoeW11cyIgPSAiY29yYWwxIiwgIlBURU4tIHRoeW11cyIgPSAiY3lhbjMiLCAiV1QgdGh5bXVzIiA9ICJjaGFydHJldXNlMyIpCgpnZ3Bsb3QoZGF0YXRoeW0sIGFlcyhmaWxsPUhUTywgeT1QZXJjZW50YWdlLCB4PUNsdXN0ZXIpKSArIAogICAgZ2VvbV9iYXIocG9zaXRpb249InN0YWNrIiwgc3RhdD0iaWRlbnRpdHkiLCB3aWR0aD0wLjcpKwogICB4bGFiKCJUaHltaWMgQ2x1c3RlcnMiKSt5bGFiKCJQZXJjZW50YWdlIikrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikrIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9Y29scywgbGFiZWxzPWMoIk15YyBQdGVuIiwiTXljIiwiUHRlbiIsIldUIikpK3RoZW1lX2xpZ2h0KCkrZ2VvbV9obGluZSh5aW50ZXJjZXB0PWMoMjUsNTAsNzUpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAiZ3JleTYwIikrIGFubm90YXRlKCJ0ZXh0IiwgeCA9IGMoMSwyLDMsNCw1LDYsNyw4KSwgeT0xMDMsIGxhYmVsID0gYyhwYXN0ZTAodGV4dCkpKQoKI3NwbGVuaWMgcHJvcG9ydGlvbnMKSWRlbnRzKFQuU2V1cmF0LnNwbGVlbikgPC0gIm1hbnVhbGNsdXN0ZXJzIgpULlNldXJhdC5zcGxlZW5iYXIgPC0gc3Vic2V0KFQuU2V1cmF0LnNwbGVlbiwgIGlkZW50cyA9IGMoIjAsNSIsIjkiLCIxIiwiMTEiLCIxOSIpKSAjdG8gb25seSBrZWVwIGNsdXN0ZXIgbmVlZGVkIGZvciB0aGUgcGxvdApkYXRhMyA8LSBkYXRhLmZyYW1lKHByb3AudGFibGUodChwcm9wLnRhYmxlKHRhYmxlKFQuU2V1cmF0LnNwbGVlbmJhckBtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnNwbGVlbmJhckBtZXRhLmRhdGEkbWFudWFsY2x1c3RlcnMpLDEpKSwxKSoxMDApCgojb3JkZXIgY2x1c3RlciBsZXZlbApkYXRhMyRWYXIxIDwtIGZhY3RvcihkYXRhMyRWYXIxLCBsZXZlbHMgPSBjKCIwLDUiLCI5IiwiMSIsIjExIiwiMTkiKSkKCmNlbGxudW1iZXIgPC0gZGF0YS5mcmFtZShjb2xTdW1zKHRhYmxlKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkbWFudWFsY2x1c3RlcnMpKSApCmNlbGxudW1iZXIkY2x1c3RlciA8LSByb3duYW1lcyhjZWxsbnVtYmVyKQpyb3dfb3JkZXIgPC1jKCIwLDUiLCI5IiwiMSIsIjExIiwiMTkiKQpjZWxsbnVtYmVyIDwtIGNlbGxudW1iZXJbcm93X29yZGVyLF0KCkNsdXN0ZXIgPC0gZGF0YTMkVmFyMQpIVE8gPC0gZGF0YTMkVmFyMgpQZXJjZW50YWdlIDwtIGRhdGEzJEZyZXEKdGV4dCA8LSBjZWxsbnVtYmVyJGNvbFN1bXMudGFibGUuVC5TZXVyYXQuc3BsZWVuLm1ldGEuZGF0YS5IVE8uLlQuU2V1cmF0LnNwbGVlbi5tZXRhLmRhdGEubWFudWFsY2x1c3RlcnMuLgojIFN0YWNrZWQgYmFyIHBsb3QKY29scyA8LSBjKCJNeWMtIFBURU4tIHNwbGVlbiIgPSAiI0ZGOTlGRiIsICJNWUMtIHNwbGVlbiIgPSAiY29yYWwxIiwgIlBURU4tIHNwbGVlbiIgPSAiY3lhbjMiLCAiV1Qgc3BsZWVuIiA9ICJjaGFydHJldXNlMyIpCgpnZ3Bsb3QoZGF0YTMsIGFlcyhmaWxsPUhUTywgeT1QZXJjZW50YWdlLCB4PUNsdXN0ZXIpKSArIAogICAgZ2VvbV9iYXIocG9zaXRpb249InN0YWNrIiwgc3RhdD0iaWRlbnRpdHkiLCB3aWR0aD0wLjcpKwogICB4bGFiKCJTcGxlbmljIENsdXN0ZXJzIikreWxhYigiUGVyY2VudGFnZSIpKyB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9Y29scywgbGFiZWxzPWMoIk15YyBQdGVuIiwiTXljIiwiUHRlbiIsIldUIikpICt0aGVtZV9saWdodCgpK2dlb21faGxpbmUoeWludGVyY2VwdD1jKDI1LDUwLDc1KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gImdyZXk2MCIpKyBhbm5vdGF0ZSgidGV4dCIsIHggPSBjKDEsMiwzLDQsNSksIHk9MTAzLCBsYWJlbCA9IGModGV4dCkpCmBgYAoKIyMjIERpZmZlcmVudGlhbCBHZW5lIEV4cHJlc3Npb24KIyMjIyBDRDgKYGBge3J9CklkZW50cyhULlNldXJhdCkgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCiNER0UgYmV0d2VlbiBvdXIgdHdvIENEOCBuYWl2ZSBjbHVzdGVycwpkZ2VjZDhfZGF0YSA8LSBGaW5kTWFya2VycyhULlNldXJhdCwgaWRlbnQuMSA9ICIxIiwgaWRlbnQuMiA9ICI0Iixsb2dmYy50aHJlc2hvbGQ9MCkKCiMgYmFyIHBsb3QKI2FkZCBhYnMgdmFsdWUgdG8gdGFibGUKZGdlY2Q4X2RhdGEkYWJzIDwtIGFicyhkZ2VjZDhfZGF0YSRhdmdfbG9nRkMpIAoKZGdlY2Q4X2RhdGEkZ2VuZW5hbWUgPC0gcm93bmFtZXMoZGdlY2Q4X2RhdGEpCiMgU2VsZWN0IG1hcmtlcnMgZm9yIHBsb3R0aW5nIG9uIGEgSGVhdG1hcCAKbWFya2Vycy51c2U9c3Vic2V0KGRnZWNkOF9kYXRhLCBwX3ZhbF9hZGo8MWUtNTAgJiBhYnM+MC4yMCkKZGZjZDhtYXJrZXJzIDwtbWFya2Vycy51c2Vbb3JkZXIobWFya2Vycy51c2UkYXZnX2xvZ0ZDKSxdCgpkZmNkOG1hcmtlcnMkZ2VuZW5hbWUgPC0gZmFjdG9yKGRmY2Q4bWFya2VycyRnZW5lbmFtZSwgbGV2ZWxzID0gZGZjZDhtYXJrZXJzJGdlbmVuYW1lW29yZGVyKGRmY2Q4bWFya2VycyRhdmdfbG9nRkMpXSkKZGZjZDhtYXJrZXJzJGxvZ3B2YWwgPC0gbG9nMTAoZGZjZDhtYXJrZXJzJHBfdmFsX2FkaikKCmdncGxvdChkZmNkOG1hcmtlcnMsIGFlcyh4ID0gZGZjZDhtYXJrZXJzJGdlbmVuYW1lLCB5ID0gZGZjZDhtYXJrZXJzJGF2Z19sb2dGQywgZmlsbCA9IGxvZ3B2YWwpKSArICAgIyBGaWxsIGNvbHVtbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAuNikgKyAgICMgZHJhdyB0aGUgYmFycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGltKC0xLjIsMS4yKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZT0iVHJ5IGRHRSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfdHVmdGUoKSArICAjIFR1ZnRlIHRoZW1lIGZyb20gZ2dmb3J0aWZ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSdyZWQnLCBtaWQ9J29yYW5nZScsIGhpZ2g9J2JsdWUnLG1pZHBvaW50ID0gLTEyMCwgYnJlYWtzPWMoLTUyLC0xMjAsLTIwMCksbGFiZWxzPWMoIi01MCIsIi0xMjAiLCItMjAwIikpK2Nvb3JkX2ZsaXAoKSAjIEZsaXAgYXhlcwpgYGAKIyMjIyBDRDQKYGBge3J9CiNkZWZpbmUgcHJvcG9ydGlvbiBvZiBnZW5vdHlwZSBpbiBDRDQgbmFpdmUgY2x1c3RlcnMKVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRtYW51YWxIVE8gPSAibm90aGluZyIKSWRlbnRzKFQuU2V1cmF0LnNwbGVlbikgPC0gIk1VTFRJX0lEIgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gIk1VTFRJX0lEIiwgaWRlbnRzID0gYygiU3BsZWVuLWN0cmwiLCJTcGxlZW4tUCIpKSxdJG1hbnVhbEhUTyA9ICJTcGxlZW4tY3RybCZQIgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gIk1VTFRJX0lEIiwgaWRlbnRzID0gYygiU3BsZWVuLU0iLCJTcGxlZW4tTVAiKSksXSRtYW51YWxIVE8gPSAiU3BsZWVuLU0mTVAiCgpwcm9wLnRhYmxlKHQocHJvcC50YWJsZSh0YWJsZShULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjgsVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRtYW51YWxIVE8pLDEpKSwyKSoxMDAKI2luIG91ciBDRDQgbmFpdmUgY2x1c3RlcnMgKDAsNSBhbmQgMTIpIHRoZSBvbmUgd2l0aCBtb3N0IGNlbGxzIGZyb20gTSZNUCBpcyAwIGFuZCB0aGUgb25lIHdpdGggbW9zdCBjZWxscyBmcm9tIGN0cmwmUCBpcyAxMgoKSWRlbnRzKFQuU2V1cmF0KSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKI0RHRSBiZXR3ZWVuIDAgYW5kIDEyCmRnZWNkNF9kYXRhIDwtIEZpbmRNYXJrZXJzKFQuU2V1cmF0LCBpZGVudC4xID0gIjAiLCBpZGVudC4yID0gIjEyIixsb2dmYy50aHJlc2hvbGQ9MCkKIyBiYXIgcGxvdAojYWRkIGFicyB2YWx1ZSB0byB0YWJsZQpkZ2VjZDRfZGF0YSRhYnMgPC0gYWJzKGRnZWNkNF9kYXRhJGF2Z19sb2dGQykgCgpkZ2VjZDRfZGF0YSRnZW5lbmFtZSA8LSByb3duYW1lcyhkZ2VjZDRfZGF0YSkKIyBTZWxlY3QgbWFya2VycyBmb3IgcGxvdHRpbmcgb24gYSBIZWF0bWFwIAptYXJrZXJzLnVzZT1zdWJzZXQoZGdlY2Q0X2RhdGEscF92YWxfYWRqPDFlLTEwICYgYWJzPjAuMikKZGZjZDRtYXJrZXJzIDwtbWFya2Vycy51c2Vbb3JkZXIobWFya2Vycy51c2UkYXZnX2xvZ0ZDKSxdCgpkZmNkNG1hcmtlcnMkZ2VuZW5hbWUgPC0gZmFjdG9yKGRmY2Q0bWFya2VycyRnZW5lbmFtZSwgbGV2ZWxzID0gZGZjZDRtYXJrZXJzJGdlbmVuYW1lW29yZGVyKGRmY2Q0bWFya2VycyRhdmdfbG9nRkMpXSkKZGZjZDRtYXJrZXJzJGxvZ3B2YWwgPC0gbG9nMTAoZGZjZDRtYXJrZXJzJHBfdmFsX2FkaikKCmdncGxvdChkZmNkNG1hcmtlcnMsIGFlcyh4ID0gZGZjZDRtYXJrZXJzJGdlbmVuYW1lLCB5ID0gZGZjZDRtYXJrZXJzJGF2Z19sb2dGQywgZmlsbCA9IGxvZ3B2YWwpKSArICAgIyBGaWxsIGNvbHVtbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAuNikgKyAgICMgZHJhdyB0aGUgYmFycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGltKC0xLjIsMS4yKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZT0iVHJ5IGRHRSBDRDQiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX3R1ZnRlKCkgKyAgIyBUdWZ0ZSB0aGVtZSBmcm9tIGdnZm9ydGlmeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0ncmVkJywgbWlkPSdvcmFuZ2UnLCBoaWdoPSdibHVlJyxtaWRwb2ludCA9IC00MCwgYnJlYWtzPWMoLTEyLC00MCwtNTcpLGxhYmVscz1jKCItMTAiLCItNDAiLCItNjAiKSkrIGNvb3JkX2ZsaXAoKSAjIEZsaXAgYXhlcwpgYGAKCiMjIyBGdW5jdGlvbmFsIHByb2ZpbCBhbmFseXNpcyAoR2VuZSBPbnRvbG9neSkKYGBge3J9CklkZW50cyhULlNldXJhdCkgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCgojIGdldCBhbGwgZ2VuZSBuYW1lIGV4cHJlc3MgaW4gb3VyIGNlbGxzIGFzIGJhY2tncm91bmQKYmFja2dyb3VuZCA8LSBULlNldXJhdEBhc3NheXMkUk5BQG1ldGEuZmVhdHVyZXMKYmFja2dyb3VuZHJvdyA8LSByb3duYW1lcyhiYWNrZ3JvdW5kKQpgYGAKCiMjIyMgTmFpdmUgQ0Q4IFQgY2VsbHMKYGBge3J9CiNER0UgYmV0d2VlbiBvdXIgdHdvIENEOCBuYWl2ZSBjbHVzdGVycwojZGdlY2Q4X2RhdGEgPC0gRmluZE1hcmtlcnMoVC5TZXVyYXQsIGlkZW50LjEgPSAiMSIsIGlkZW50LjIgPSAiNCIsbG9nZmMudGhyZXNob2xkPTApCiN1cHJlZ19jZDggPC0gc3Vic2V0KGRnZWNkOF9kYXRhLCBhdmdfbG9nRkM+MCkKI2Rvd25yZWdfY2Q4IDwtIHN1YnNldChkZ2VjZDhfZGF0YSwgYXZnX2xvZ0ZDPDAuMiAmIHBfdmFsX2FkajwxZS01MCkKI2dlbmVjb21wcm93IDwtIHJvd25hbWVzKGRvd25yZWdfY2Q4KQoKCiMjIyMgVE8gU1VQUFJFU1MgRk9SIEZJTkFMCiN3cml0ZS50YWJsZShnZW5lY29tcHJvdyxmaWxlPSIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL2NsdXN0ZXIxdjQudHh0IixzZXA9Ilx0IixxdW90ZT1GKQpnZW5lY29tcHJvdyA8LSByZWFkLnRhYmxlKCIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL2NsdXN0ZXIxdjQudHh0Iiwgc2VwID0gIlx0IikKZ2VuZWNvbXByb3ckeCA9IGFzLmNoYXJhY3RlcihnZW5lY29tcHJvdyR4KQpnZW5lY29tcHJvdyA8LSBnZW5lY29tcHJvd1ssMV0KIyMjIwoKQ1BlbnJpY2ggPC0gZW5yaWNoR08oZ2VuZT0gZ2VuZWNvbXByb3csIE9yZ0RiID0gJ29yZy5NbS5lZy5kYicsIG9udD0iQlAiLGtleVR5cGUgPSAiU1lNQk9MIix1bml2ZXJzZSA9IGJhY2tncm91bmRyb3cpICMgb3JnLk1tLmVnLmRiIGdlbm9tZSBtb3VzZQpoZWFkIChDUGVucmljaCkKCmRvdHBsb3QoQ1BlbnJpY2gsIHNob3dDYXRlZ29yeT0xNSxjb2xvciA9ICJwLmFkanVzdCIseD0iY291bnQiKSAjKyBjb29yZF9mbGlwKCkrdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmVtYXBwbG90KENQZW5yaWNoLCBzaG93Q2F0ZWdvcnkgPSA1MCkKYGBgCgojIyMjIE5haXZlIENENCBUIGNlbGxzCmBgYHtyfQojREdFIGJldHdlZW4gb3VyIHR3byBtb3N0IGNvbnRyb2wgYW5kIE15ZCBkZWwgQ0Q0IG5haXZlIGNsdXN0ZXJzCiNkZ2VjZDRfZGF0YSA8LSBGaW5kTWFya2VycyhULlNldXJhdCwgaWRlbnQuMSA9ICIwIiwgaWRlbnQuMiA9ICIxMiIsbG9nZmMudGhyZXNob2xkPTApCiNkb3ducmVnX2NkNCA8LSBzdWJzZXQoZGdlY2Q0X2RhdGEsIGF2Z19sb2dGQzwwJiBwX3ZhbF9hZGo8MWUtMjApCiNnZW5lY29tcHJvdyA8LSByb3duYW1lcyhkb3ducmVnX2NkNCkKCgojIyMjIFRPIFNVUFBSRVNTIEZPUiBGSU5BTAojd3JpdGUudGFibGUoZ2VuZWNvbXByb3csZmlsZT0iL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvMDFfVGhlc2UvMDFfUHJvamVjdC9NeWNfUHRlbl9QYXBlci9jbHVzdGVyMHZzMTIudHh0IixzZXA9Ilx0IixxdW90ZT1GKQpnZW5lY29tcHJvdyA8LSByZWFkLnRhYmxlKCIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL2NsdXN0ZXIwdnMxMi50eHQiLCBzZXAgPSAiXHQiKQpnZW5lY29tcHJvdyR4ID0gYXMuY2hhcmFjdGVyKGdlbmVjb21wcm93JHgpCmdlbmVjb21wcm93IDwtIGdlbmVjb21wcm93WywxXQojIyMjCgoKQ1BlbnJpY2ggPC0gZW5yaWNoR08oZ2VuZT0gZ2VuZWNvbXByb3csIE9yZ0RiID0gJ29yZy5NbS5lZy5kYicsIG9udD0iQlAiLGtleVR5cGUgPSAiU1lNQk9MIix1bml2ZXJzZSA9IGJhY2tncm91bmRyb3cpICMgb3JnLk1tLmVnLmRiIGdlbm9tZSBtb3VzZQoKZG90cGxvdChDUGVucmljaCwgc2hvd0NhdGVnb3J5PTE1LGNvbG9yID0gInAuYWRqdXN0Iix4PSJjb3VudCIpKyBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1mdW5jdGlvbih4KXN0cl93cmFwKHgsIHdpZHRoPTQwKSkKYGBgCgojIyMgZVlGUCBuZWdhdGl2ZSBpbnZlc3RpZ2F0aW9uCkRlY2lwaGVyaW5nIHdoYXQgYXJlIG91ciBlWUZQIG5lZ2F0aXZlIGNlbGxzIG9uIGVmZmVjdG9yIGFuZCBtZW1vcnkgQ0Q4IFQgY2VsbHMKCkhlYXRtYXAgOiAKYGBge3J9CiMgT24gY2x1c3RlciAxMSAtIGNkOCBtZW1vcnkKQzExQ3RybCA8LXJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxMSIsXSkKbUMxMUN0cmwgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTFDdHJsXSkKQzExUHQgPC0gcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjExIixdKQptQzExUHQgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTFQdF0pCkMxMU1QIDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTEiLF0pCm1DMTFNUCA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxMU1QXSkKQzExTSA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTEiLF0pCm1DMTFNIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzExTV0pCiNvbiBjbHVzdGVyIDE5IC0gY2Q4IGVmZiB0ZXJtCkMxOUN0cmwgPC1yb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTkiLF0pCm1DMTlDdHJsIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzE5Q3RybF0pCkMxOVB0IDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLVAiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxOSIsXSkKbUMxOVB0IDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzE5UHRdKQpDMTlNUCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjE5IixdKQptQzE5TVAgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTlNUF0pCkMxOU0gPC0gcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tTSIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjE5IixdKQptQzE5TSA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxOU1dKQojb24gY2x1c3RlciAxCkMxQ3RybCA8LXJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxIixdKQptQzFDdHJsIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzFDdHJsXSkKQzFQdCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMSIsXSkKbUMxUHQgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMVB0XSkKQzFNUCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjEiLF0pCm1DMU1QIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzFNUF0pCkMxTSA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMSIsXSkKbUMxTSA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxTV0pCgoKbDEgPC0gYygiMSIsIjEiLCIxIiwiMSIsIjExIiwiMTEiLCIxMSIsIjExIiwiMTkiLCIxOSIsIjE5IiwiMTkiKQpsMiA8LSBjKCJDdHJsIiwiUHRlbiIsIk15YyIsIk15Y1B0ZW4iLCJDdHJsIiwiUHRlbiIsIk15YyIsIk15Y1B0ZW4iLCJDdHJsIiwiUHRlbiIsIk15YyIsIk15Y1B0ZW4iKQpsMyA8LSBjKG1DMUN0cmwsbUMxUHQsbUMxTSxtQzFNUCxtQzExQ3RybCxtQzExUHQsbUMxMU0sbUMxMU1QLG1DMTlDdHJsLG1DMTlQdCxtQzE5TSxtQzE5TVApCgp0YWJsZWF1WUZQIDwtIGRhdGEuZnJhbWUoQ2x1c3RlciA9IGwxLCBHZW5vdHlwZXMgPWwyKSAKdGFibGVhdVlGUCA8LSBjYmluZCh0YWJsZWF1WUZQLFZhbHVlcyA9IGwzKQoKCnRhYmxlYXVZRlAkQ2x1c3RlciA8LSBmYWN0b3IodGFibGVhdVlGUCRDbHVzdGVyLGxldmVscyA9IGMoIjEiLCIxMSIsIjE5IikpCnRhYmxlYXVZRlAkR2Vub3R5cGVzIDwtIGZhY3Rvcih0YWJsZWF1WUZQJEdlbm90eXBlcyxsZXZlbHMgPSBjKCJNeWNQdGVuIiwiTXljIiwiUHRlbiIsIkN0cmwiKSkKYGBgCgpgYGB7cn0KZ2dwbG90KHRhYmxlYXVZRlAsIGFlcyh4ID0gQ2x1c3RlciwgR2Vub3R5cGVzKSkgKwogICAgICAgIGdlb21fdGlsZShhZXMoZmlsbCA9IFZhbHVlcykpICsKICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50MiggbWlkPSd5ZWxsb3cnLCBoaWdoPSdyZWQnLGxpbWl0cz1jKDAsbWF4KHRhYmxlYXVZRlAkVmFsdWVzKSkpKyB0aGVtZV9jbGFzc2ljKGJhc2Vfc2l6ZT0yMCkKYGBgCgplWUZQIG5lYWd0aXZlIGFyZSBjb21pbmcgZnJvbSBNeWMgYW5kIE15YyBQdGVuIGRlbCBtaWNlCgpgYGB7cn0KI0RPVCBwbG90IGV5RlAgYW5kIFRHRCBvbiBDRDggZWZmZWN0b3IgYW5kIG1lbW9yeQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKQ0Q4c3ViIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sIGlkZW50cyA9IGMoIjExIiwiMTkiLCIxMyIpKQpJZGVudHMoQ0Q4c3ViKSA8LSAiTVVMVElfSUQiCkNEOHN1YkBhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKENEOHN1YkBhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIlNwbGVlbi1NIiwiU3BsZWVuLU1QIiwiU3BsZWVuLWN0cmwiLCJTcGxlZW4tUCIpKQpsZXZlbHMoQ0Q4c3ViKQpgYGAKCmBgYHtyfQpEb3RQbG90KENEOHN1YiwgZG90LnNjYWxlID0gOCxmZWF0dXJlcyA9IGMoIlRjcmctQzEiLCJUcmRjIiwiVHJiYzIiLCJUcmFjIiwiZVlGUCIpICkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpKyBnZ3RpdGxlKCJDRDggbWVtb3J5IGFuZCBlZmZlY3RvciBjbHVzdGVycyIpCmBgYApleUZQIG5lZ2F0aXZlIGFyZSBjb21pbmcgZnJvbSBNeWMgYW5kIE15YyBQdGVuIGRlbCBtaWNlIGFuZCBhcmUgVGdkIGNlbGxzLgoKI1Nlc3Npb24gSW5mbwpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAK